<?php
/**
 * @name 继承View使用smarty
 *
 * LICENSE
 *
 * This source file is subject to the BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.phpxe.com/license/
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to Chaodong.Sheng <scd113@gmail.com> so we can send you a copy immediately.
 *
 * @category   View of Scd Framework
 * @package    Scd
 * @copyright  Copyright (c) 2007 PHPXe Web Studio <http://www.phpxe.com>
 * @license    http://framework.phpxe.com/license/
 * @version    $Id: smarty.php Sun Sep 23 23:29:01 CST 2007 Davy $
 */
include_once("Scd/View/Abstract.php");
include_once("Scd/View/Exception.php");

class Scd_View_Smarty extends Scd_View_Abstract {

	var $_engine = null;
	var $_theme;

	/**
	 * 初始化
	 *
	 * @return Smarty
	 */
	function Scd_View_Smarty( $env )
	{
		$this->_theme = $env->theme;//
		define('SMARTY_PATH', $env->smarty_path);
		include_once(SMARTY_PATH."/Smarty.class.php");
		$this->_engine = new Smarty();
		$this->_engine->debugging		= $env->tplbug;
		//$this->_engine->template_dir 	= $env->template_dir."/s%";
		$this->_engine->template_dir 	= $env->template_dir;
		//$this->_engine->compile_dir 	= $env->compile_dir."/s%";
		$this->_engine->compile_dir 	= $env->compile_dir;
		$this->_engine->config_dir 		= $env->config_dir;
		$this->_engine->cache_dir 		= $env->cache_dir;
		//$this->_engine->plugins_dir   = 'Scd/View/libs/plugins';
		if ($env->preCompiled) {//是否预编译替换相关路径
			$this->_engine->register_prefilter("smarty_prefilter_preCompile");
		}
		$this->_engine->left_delimiter	= $env->left_delimiter ? $env->left_delimiter : "{";
		$this->_engine->right_delimiter	= $env->right_delimiter ? $env->right_delimiter : "}";
		$this->_engine->Caching = true;
		return $this;
	}
	
	/**
	 * 覆盖template_dir和compile路径
	 */
	function setTemplateDir($controllerPath)
	{
		//theme是否存在？
		$themeDir = APPROOT.sprintf($this->_engine->compile_dir, '').$this->_theme;
		if (!file_exists($themeDir)) {
			createDir($themeDir);
		}
		$this->_engine->template_dir = sprintf($this->_engine->template_dir, $controllerPath);
		if (file_exists(APPROOT.$this->_engine->template_dir)) {
			createDir(APPROOT.$this->_engine->template_dir);
		}
		$this->_engine->compile_dir = sprintf($this->_engine->compile_dir, $controllerPath);
		//echo APPROOT.$this->_engine->compile_dir;
		if (!file_exists(APPROOT.$this->_engine->compile_dir)) {
			createDir(APPROOT.$this->_engine->compile_dir);
		}
		return $this;
	}

	/**
	 * @desc 用于传递每个页面都需要的默认变量等
	 * @auth 被子类调用
	 */
	function _defaultTemplateVariables()
	{
		$arr = array(
		'curUri'	=> $_SERVER['REQUEST_URI'],
		);
		return $arr;
	}

	/**
	 * @name Factory
	 * 处理赋值等。
	 */
	function factory( $array )
	{
		foreach($this->_defaultTemplateVariables() as $key => $value) {
			$this->assign($key, $value);
		}
		if (!is_array($array)) {
			return new Scd_View_Exception("#__Is not array!");
		}
		foreach($array as $key => $value) {
			$this->assign($key, $value);
		}
	}

	/**
	 * @set
	 */
	function set($key, $value = null )
	{
		if ($key == '') {
			new Scd_View_Exception("没有传入KEY；smarty没有赋值！");
		}
		$this->assign($key, $value);
	}

	/**
	 * @name 赋值
	 */
	function assign($spec, $value = null)
	{
		// if $spec is a string, then assign $value othwerise, if $spec is an
		// array, then assign each element of the array
		if (is_string($spec)) {
			if($value !== null) {
				$this->_engine->assign($spec, $value);
			} else {
				return new Scd_View_Exception('assign() expects a string to have a value');
			}
		} elseif (is_array($spec)) {
			foreach ($spec as $key => $val) {
				$this->_engine->assign($key, $val);
			}
		} else {
			return new Scd_View_Exception('assign() expects a string or array, got ' . gettype($spec));
		}
	}

	/**
	 * 编译模版
	 *
	 * @param 地址 $name
	 */
	function display($name)
	{
		return $this->_engine->display($name);
	}

	/**
	 * fetch
	 *
	 * @param unknown_type $name
	 * @return unknown
	 */
	function render($name)
	{
		return $this->_engine->fetch($name);
	}
	
	/**
	 * 输出this
	 *
	 */
	function toString()
	{
		if (!function_exists('dump')) {
			include("Scd/Util/Debug.php");
		}
		dump($this);
	}
}

/**
 * 插件
 *
 * @param unknown_type $source
 * @param unknown_type $smarty
 * @return unknown
 */
function smarty_prefilter_preCompile($source, &$smarty)
{
	global $theme;
	//用验证adminAuth的方法验证取那部分的路径
	//$theme = $tmp->ftheme;
	$file_type = strtolower(strrchr($smarty->_current_file, '.'));
	$tmp_dir   = '/phpxe/www/'.$theme.'/'; // 模板所在路径
	$source = replace_source($tmp_dir, $source);
	return $source;
}
function replace_source($tmp_dir, $source)
{
	/* 将模板中所有library替换为链接 */
	$pattern     = '/<!--\s#BeginLibraryItem\s\"\/(.*?)\"\s-->.*?<!--\s#EndLibraryItem\s-->/se';
	$source 	 = preg_replace('/\/phpxe\/www\//', '', $source);

	$replacement = "'{include file='.strtolower('\\1'). '}'";
	$source      = preg_replace($pattern, $replacement, $source);

	/* 在头部加入版本信息 */
	$source = preg_replace('/<head>/i', "<head>\r\n<meta name=\"Generator\" content=\"" . APPNAME .' ' . VERSION . "\" />",  $source);

	/* 替换相对链接 */
	$source = preg_replace('/(href=["|\'])\.\.\/(.*?)(["|\'])/i', '\1\2\3', $source);

	/* 修正css路径 */
	$source = preg_replace('/(<link\shref=["|\'])(?:\.\/|\.\.\/)?(css\/)?([a-z0-9A-Z_]+\.css["|\']\srel=["|\']stylesheet["|\']\stype=["|\']text\/css["|\'])/i','\1' . addslashes($tmp_dir) . '\2\3', $source);

	/* 修正js目录下js的路径 */
	$source = preg_replace('/(<script\s(?:type|language)=["|\']text\/javascript["|\']\ssrc=["|\'])(?:\.\/|\.\.\/)?(js\/[a-z0-9A-Z_]+\.(?:js|vbs)["|\']><\/script>)/', '\1' . $tmp_dir . '\2', $source);

	/* 修正模板中对images目录下的链接 */
	$source = preg_replace('/((?:background|src)\s*=\s*["|\'])(?:\.\/|\.\.\/)?(images\/.*?["|\'])/is', '\1' . $tmp_dir . '\2', $source);
	$source = preg_replace('/((?:background|background-image):\s*?url\()(?:\.\/|\.\.\/)?(images\/)/is', '\1' . $tmp_dir . '\2', $source);

	/* 替换文件编码头部 */
	if (strpos($source, "\xEF\xBB\xBF") !== FALSE)
	{
		$source = str_replace("\xEF\xBB\xBF", '', $source);
	}
	/* 替换smarty注释 */
	$pattern = '/<!--[^>|\n]*?({.+?})[^<|{|\n]*?-->/';
	$source  = preg_replace($pattern, '\1', $source);

	/* 替换不换行的html注释 */
	$pattern = '/<!--[^<|>|{|\n]*?-->/';
	$source  = preg_replace($pattern, '', $source);
	return $source;
}

function createDir($dirName)
{
	if (file_exists($dirName)) {
		return false;
	}else {
		mkdir($dirName);
		chmod($dirName, 0777);
	}
}
?>